package loja.view.editor.components.frame;

import static loja.view.editor.components.StatesEditor.*;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import loja.model.handler.HandlerViewEntity;
import loja.view.editor.components.ComponentEditor;
import loja.view.editor.components.ContainerEditor;
import loja.view.editor.components.StatesEditor;
import loja.view.editor.components.panel.EntityPanelEditor;
import loja.view.editor.components.panel.PanelTitle;
import loja.view.editor.components.table.TableEditor;
import loja.view.editor.components.tablemodel.EntityTableModel;

public abstract class EntityFrameEditor<T, PK> extends JInternalFrame implements
		ContainerEditor {

	private static final long serialVersionUID = 1L;

	protected JButton btCancel, btEdit, btNew, btRemove, btSave;
	protected Filler filler1, filler2, filler3;
	protected JScrollPane jScrollPaneEditor, jScrollPaneTable;
	protected JLabel lblStatus, lblTitle;
	protected JPanel panelButtons, panelEditor, panelStatus;
	protected JTabbedPane panelMain;
	protected PanelTitle panelTitle;
	protected TableEditor table;
	protected Dimension dimension1, dimension2, dimension3;
	protected HandlerViewEntity<T, PK> handlerViewEntity;
	protected String labelTitle = "DefaultFrameEditor";
	
	private List<ComponentEditor> componentsEditor;
	private EntityTableModel<T> tableModel;
	private EntityPanelEditor<T, PK> entityPanelEditor;
	private List<T> entities;
	


	public EntityFrameEditor(HandlerViewEntity<T, PK> handlerViewEntity) {

		this.handlerViewEntity = handlerViewEntity;
		this.tableModel = createTableModel();
		this.entityPanelEditor = createEntityPanelEditor();
		this.componentsEditor = new ArrayList<>();
		this.entities = new ArrayList<>();

		panelTitle = new PanelTitle();
		panelStatus = new JPanel();
		panelMain = new JTabbedPane();
		panelEditor = new JPanel();
		panelButtons = new JPanel();

		lblTitle = new JLabel();
		lblStatus = new JLabel();

		jScrollPaneTable = new JScrollPane();
		jScrollPaneEditor = new JScrollPane();

		table = new TableEditor();

		dimension1 = new java.awt.Dimension(10, 20);
		dimension2 = new java.awt.Dimension(0, 0);
		dimension3 = new java.awt.Dimension(32767, 0);

		filler1 = new Filler(dimension1, dimension1, dimension1);
		filler2 = new Filler(dimension1, dimension1, dimension1);
		filler3 = new Filler(dimension2, dimension2, dimension3);

		btEdit = new JButton();
		btNew = new JButton();
		btSave = new JButton();
		btCancel = new JButton();
		btRemove = new JButton();

		initTableModel();

		addComponentEditor(entityPanelEditor);
		addComponentEditor(table);

	}

	protected abstract EntityPanelEditor<T, PK> createEntityPanelEditor();

	protected abstract EntityTableModel<T> createTableModel();

	public void updateTable(List<T> entities) {
		this.entities = entities;
		tableModel.setEntities(entities);
		table.setModel(tableModel);
	}

	public void setButtonsActionListener(ActionListener actionListener) {

		btCancel.addActionListener(actionListener);
		btEdit.addActionListener(actionListener);
		btNew.addActionListener(actionListener);
		btRemove.addActionListener(actionListener);
		btSave.addActionListener(actionListener);

	}

	@Override
	public void onCancel() {
		setEnableButtonsForEdition(false);
		setStateForComponentEditor(componentsEditor, CANCEL);
	}

	@Override
	public void onEdit() {
		setEnableButtonsForEdition(true);
		setStateForComponentEditor(componentsEditor, EDIT);
	}

	@Override
	public void onEnd() {
		setStateForComponentEditor(componentsEditor, END);
	}

	@Override
	public void onInclude() {
		setEnableButtonsForEdition(true);
		setStateForComponentEditor(componentsEditor, INCLUDE);
	}

	@Override
	public void onRemove() {
		setEnableButtonsForEdition(false);
		setStateForComponentEditor(componentsEditor, REMOVE);
	}

	@Override
	public void onSave() {
		setEnableButtonsForEdition(false);
		setStateForComponentEditor(componentsEditor, SAVE);
	}

	@Override
	public void addComponentEditor(ComponentEditor componentEditor) {
		componentsEditor.add(componentEditor);
	}

	@Override
	public void removeComponentEditor(ComponentEditor componentEditor) {
		componentsEditor.remove(componentEditor);
	}

	@Override
	public void onStart() {

		setClosable(true);
		setIconifiable(true);
		setMaximizable(true);
		setResizable(true);
		setPreferredSize(new java.awt.Dimension(600, 600));

		panelTitle.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
		lblTitle.setFont(new java.awt.Font("Calibri", 0, 24));
		lblTitle.setForeground(new java.awt.Color(0, 102, 153));
		lblTitle.setText(labelTitle);
		lblTitle.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		panelTitle.add(lblTitle);

		jScrollPaneTable.setBorder(null);

		table.setModel(tableModel);

		table.setBorder(null);
		table.getSelectionModel().addListSelectionListener(
				new ListSelectionListener() {

					@Override
					public void valueChanged(ListSelectionEvent e) {
						if (table.isEnabled() && table.getSelectedRow() > -1) {
							T entity = tableModel.getEntities().get(
									table.getSelectedRow());
							handlerViewEntity.setEntity(entity);
							btEdit.setEnabled(true);
						}
					}
				});

		jScrollPaneTable.setViewportView(table);

		panelMain.addTab("Tabela", jScrollPaneTable);

		panelEditor.add(entityPanelEditor);

		panelEditor.setLayout(new FlowLayout(FlowLayout.LEFT));

		jScrollPaneEditor.setViewportView(panelEditor);
		jScrollPaneEditor.setBorder(null);

		panelMain.add("Detalhes", jScrollPaneEditor);

		panelButtons.setLayout(new javax.swing.BoxLayout(panelButtons,
				javax.swing.BoxLayout.LINE_AXIS));

		btEdit.setText("Editar");
		btNew.setText("Novo");
		btSave.setText("Salvar");
		btCancel.setText("Cancelar");
		btRemove.setText("Remover");

		panelButtons.add(btEdit);
		panelButtons.add(filler1);

		panelButtons.add(btNew);
		panelButtons.add(filler3);
		panelButtons.add(btSave);
		panelButtons.add(filler2);
		panelButtons.add(btCancel);
		panelButtons.add(btRemove);

		panelStatus.setBorder(javax.swing.BorderFactory
				.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));

		getContentPane().setLayout(new GridBagLayout());

		GridBagConstraints c = new GridBagConstraints();

		c.anchor = GridBagConstraints.NORTH;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridy = 1;

		add(panelTitle, c);

		c.anchor = GridBagConstraints.SOUTH;
		c.gridy = 3;
		c.insets = new Insets(10, 10, 10, 10);

		add(panelButtons, c);

		c.anchor = GridBagConstraints.WEST;
		c.fill = GridBagConstraints.BOTH;
		c.gridy = 2;
		c.weightx = 1;
		c.weighty = 1;

		add(panelMain, c);

		StatesEditor.setStateForComponentEditor(componentsEditor,
				StatesEditor.START);

		setEnableButtonsForEdition(false);
		pack();
		
		setVisible(true);

	}

	private void setEnableButtonsForEdition(boolean enabled) {

		btCancel.setVisible(enabled);
		btEdit.setVisible(!enabled);
		btNew.setVisible(!enabled);
		btRemove.setVisible(!enabled);
		btSave.setVisible(enabled);

		if (enabled) {
			panelMain.setSelectedIndex(1);
		} else {
			panelMain.setSelectedIndex(0);
			btEdit.setEnabled(false);
		}

		panelMain.setEnabledAt(0, !enabled);
	}

	private void initTableModel() {
		if (tableModel != null)
			tableModel.setEntities(entities);
	}
}
